package chat;

public class PeerInfo
{
    private String zID = "";
    private String zChatName;
    private String zAddresses;
    private Integer zPort = null;
    private String[] zOldChatNames = null;
    private static final String NO_CHATNAME = "(?)";

    public PeerInfo( String pChatName , String pAddresses )
    {
        zChatName = (pChatName != null) ? pChatName : NO_CHATNAME;
        IllegalArgument.ifNull( "Addresses" , zAddresses = pAddresses );
    }

    public PeerInfo( String pChatName , String pAddresses , int pPort )
    {
        this( pChatName , pAddresses );
        zPort = new Integer( pPort );
    }

    public void updateWith( PeerInfo pPeerInfo )
    {
        if ( pPeerInfo != null )
        {
            setChatName( pPeerInfo.getChatName() );
            setAddresses( pPeerInfo.getAddresses() );
            setPort( pPeerInfo.getPort() );
        }
    }

    public static PeerInfo deFormat( String pFormatted )
    {
        IllegalArgument.ifNull( "Formatted" , pFormatted );
        int colonAt = pFormatted.indexOf( ':' );
        int spaceAt = pFormatted.indexOf( ' ' );
        if ( (colonAt == -1) || (spaceAt == -1) )
            return null;
        String chatName = pFormatted.substring( spaceAt + 1 );
        String addresses = pFormatted.substring( 0 , colonAt );
        int port = 0;
        try
        {
            port = Integer.parseInt( pFormatted.substring( colonAt + 1 , spaceAt ) );
        }
        catch ( NumberFormatException shouldNotHappenSoWeIgnoreThisMessage )
        {
            return null;
        }
        return new PeerInfo( chatName , addresses , port );
    }

    public boolean isAddressable()
    {
        return ((zAddresses != null) && (zPort != null));
    }

    public String getID()
    {
        return zID;
    }

    public void setID( String pID )
    {
        IllegalArgument.ifNull( "ID" , zID = pID );
    }

    public String getChatName()
    {
        return zChatName;
    }

    public String[] getOldChatNames()
    {
        return zOldChatNames;
    }

    public synchronized String getPrevChatName()
    {
        return (zOldChatNames == null) ? null : zOldChatNames[ 0 ];
    }

    public synchronized void setChatName( String pChatName )
    {
        if ( (pChatName != null) && !pChatName.equals( zChatName ) )
        {
            if ( (zChatName != null) && !zChatName.equals( NO_CHATNAME ) )
            {
                if ( zOldChatNames == null )
                    zOldChatNames = new String[ 1 ];
                else
                {
                    String[] temp = new String[ zOldChatNames.length + 1 ];
                    System.arraycopy( zOldChatNames , 0 , temp , 1 , zOldChatNames.length );
                    zOldChatNames = temp;
                }
                zOldChatNames[ 0 ] = zChatName;
            }
            zChatName = pChatName;
        }
    }

    public String getAddresses()
    {
        return zAddresses;
    }

    public void setAddresses( String pAddresses )
    {
        IllegalArgument.ifNull( "Addresses" , zAddresses = pAddresses );
    }

    public int getPort()
    {
        return (zPort == null) ? 0 : zPort.intValue();
    }

    public void setPort( int pPort )
    {
        zPort = new Integer( pPort );
    }

    public String format()
    {
        return zAddresses + ":" + zPort + " " + zChatName;
    }

    public int hashCode()
    {
        int retval = 0;
        if ( zAddresses != null )
            retval += zAddresses.hashCode();
        if ( zPort != null )
            retval += zPort.hashCode();
        return retval;
    }

    public boolean equals( String pAddresses , Integer pPort )
    {
        if ( zAddresses != pAddresses )
        {
            if ( zAddresses == null )
                return false;
            if ( zAddresses.equals( pAddresses ) == false )
                return false;
        }
        if ( zPort != pPort )
        {
            if ( zPort == null )
                return false;
            if ( zPort.equals( pPort ) == false )
                return false;
        }
        return true;
    }

    public boolean equals( PeerInfo pOther )
    {
        return (pOther == null) ? false : equals( pOther.zAddresses , pOther.zPort );
    }

    public boolean equals( Object obj )
    {
        if ( obj instanceof PeerInfo ) // Note: Use of instanceof is so that MyInfo can be compared.
            return equals( (PeerInfo) obj );
        return false;
    }

    public String toString()
    {
        String retval = zID + " " + zChatName + " " + zAddresses + ":" + ((zPort != null) ? zPort.toString() : "?");

        String[] oldnames = getOldChatNames();
        if ( oldnames != null )
            for ( int i = 0 ; i < oldnames.length ; i++ )
                retval += " -> " + oldnames[ i ];

        return retval;
    }
}
